package cn.xuchunh.campusbbs.crash;

import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Environment;
import android.os.StatFs;
import android.text.format.Time;

import cn.xuchunh.campusbbs.AppContext;
import cn.xuchunh.campusbbs.bean.User;

public class CrashDataFactory {

	public static final String CRASHDATA_CACHE = "crash_data";

	public static void createCrashData(Throwable th, Thread brokenThread,
			Context context) {
		CrashData data = new CrashData();
		User user = AppContext.getInstance().getUser();
		if (user == null) {
			data.setUserName("unknown");
			data.setName("unkown");
		} else {
			data.setUserName(user.getUserName());
		}
		try {
			PackageInfo packageInfo = context.getPackageManager()
					.getPackageInfo(context.getPackageName(), 0);
			data.setAppCode(Integer.toString(packageInfo.versionCode));
			data.setAppVersion(packageInfo.versionName);
		} catch (NameNotFoundException e) {
			data.setAppCode("unknown");
			data.setAppVersion("unknown");
		}
		Time time = new Time();
		time.setToNow();
		data.setTime(time.format3339(false));
		data.setAndroidVerison(android.os.Build.VERSION.RELEASE);
		data.setBrand(android.os.Build.BRAND);
		data.setProduct(android.os.Build.PRODUCT);
		data.setStack(getStackTrace(th));
		data.setTotalMem(Long.toString(getTotalInternalMemorySize()));
		data.setAvailbleMem(Long.toString(getAvailableInternalMemorySize()));
		AppContext.getInstance().getCache().put(CRASHDATA_CACHE, data);
	}

	public static String getStackTrace(Throwable th) {

		final Writer result = new StringWriter();
		final PrintWriter printWriter = new PrintWriter(result);

		// If the exception was thrown in a background thread inside
		// AsyncTask, then the actual exception can be found with getCause
		Throwable cause = th;
		while (cause != null) {
			cause.printStackTrace(printWriter);
			cause = cause.getCause();
		}
		final String stacktraceAsString = result.toString();
		printWriter.close();

		return stacktraceAsString;
	}

	@SuppressWarnings("deprecation")
	public static long getTotalInternalMemorySize() {
		final File path = Environment.getDataDirectory();
		final StatFs stat = new StatFs(path.getPath());
		final long blockSize = stat.getBlockSize();
		final long totalBlocks = stat.getBlockCount();
		return totalBlocks * blockSize;
	}

	@SuppressWarnings("deprecation")
	public static long getAvailableInternalMemorySize() {
		final File path = Environment.getDataDirectory();
		final StatFs stat = new StatFs(path.getPath());
		final long blockSize = stat.getBlockSize();
		final long availableBlocks = stat.getAvailableBlocks();
		return availableBlocks * blockSize;
	}

}
